library(data.table)
library(lubridate)
library(stringi)
library(stringr)
library(ggplot2)
library(ggthemes)
library(scales)
library(showtext)

# Declare working directory beforehand in an environment variable
# IMPERIAL_LEGAL_POLITICS_REPLICATION_PATH = "path_to_your_folder"
# with the aid of usethis::edit_r_environ()
# Restart R session for the changes to take effect
path <- Sys.getenv("IMPERIAL_LEGAL_POLITICS_REPLICATION_PATH")
setwd(path)

# Load an object with case-instance-side-outcome-level data
load("data/krasnodar_case_outcomes_side_instance.rdata")

# Font for plotting
font_name <- "Arial"
showtext_auto()

##############################
# Aggregate data at case level (with first instance taking precedence)

cols_to_keep <- c("caseid", "caseTypeCode", "caseCategoryUnified", "caseCategoryRedux", "caseCategory_government", "caseCategory_private", "year", "year_factor", "petty_case", "countDocumentsByCourt", "lncountDocumentsByCourt", "days_elapsed", "claimSum_deflated", "claimSum_decile", "recoverySum_deflated", "was_appealed", "registrationDate", "date", "dispute_type", "local_entities_only", names(krasnodar_case_outcomes_side_instance)[grepl("judge|government|agency|local_entity", names(krasnodar_case_outcomes_side_instance))])

krasnodar_cases <- krasnodar_case_outcomes_side_instance[, lapply(.SD, function(x) x[[1]]), by = "caseid", .SDcols = cols_to_keep ]
krasnodar_cases[, c("government", "federal_agency", "regional_agency", "municipal_agency", "local_entity") := NULL ]

##############################
# Create judge-level characteristics

# Long object with all judge ids and names for each case
temp <- rbindlist(list(krasnodar_case_outcomes_side_instance[!is.na(presiding_judge), c("caseid", "instanceLevel", "presiding_judgeId", "presiding_judge", "presiding_judge_krasnodar"), with = F],
	krasnodar_case_outcomes_side_instance[!is.na(judgeId_1), c("caseid", "instanceLevel", "judgeId_1", "judge_1", "judge_1_krasnodar"), with = F],
	krasnodar_case_outcomes_side_instance[!is.na(judgeId_2), c("caseid", "instanceLevel", "judgeId_2", "judge_2", "judge_2_krasnodar"), with = F],
	krasnodar_case_outcomes_side_instance[!is.na(judgeId_3), c("caseid", "instanceLevel", "judgeId_3", "judge_3", "judge_3_krasnodar"), with = F],
	krasnodar_case_outcomes_side_instance[!is.na(judgeId_4), c("caseid", "instanceLevel", "judgeId_4", "judge_4", "judge_4_krasnodar"), with = F],
	krasnodar_case_outcomes_side_instance[!is.na(judgeId_5), c("caseid", "instanceLevel", "judgeId_5", "judge_5", "judge_5_krasnodar"), with = F]),
	use.names = F
)
setnames(temp, c("caseid", "instanceLevel", "judgeId", "judgeName", "krasnodar"))
temp <- unique(temp, by = c("caseid", "judgeId"))

# Attach selected case characteristics
judge_chars <- merge(temp, krasnodar_cases[, c("caseid", "year", "involved_government", "involved_federal_agency", "involved_regional_agency", "involved_municipal_agency", "involved_local_entity", "government_plaintiff", "federal_agency_plaintiff", "regional_agency_plaintiff", "municipal_agency_plaintiff", "local_entity_plaintiff", "caseTypeCode", "caseCategoryRedux", "caseCategory_government", "caseCategory_private", "petty_case", "claimSum_deflated", "government_win_first", "government_win_final", "federal_agency_win_final", "regional_agency_win_final", "municipal_agency_win_final", "local_entity_win_final", "was_appealed", "local_entities_only")], by = "caseid", all.x = T, all.y = F)

# Attach selected case characteristics that are instance-varying
judge_chars <- merge(judge_chars, unique(krasnodar_case_outcomes_side_instance[, c("caseid", "instanceLevel", "countDocumentsByCourt", "days_elapsed")], by = c("caseid", "instanceLevel")), by = c("caseid", "instanceLevel"), all.x = T, all.y = F)

##############################
# TABLE 2. Descriptive statistics at judge level: Crimea and Sevastopol and Krasnodar arbitrazh courts in 2012/14–2019

# All judges table by appeal level
government_judges_table_all <- judge_chars[ involved_government == 1 & !is.na(new), list(
	`01_judges` = uniqueN(judgeName),
	`02_total_government_cases` = sum(involved_government),
	`01a_involving_federal_agency` = round(100*mean(involved_federal_agency, na.rm = T), 1),
	`01b_involving_regional_agency` = round(100*mean(involved_regional_agency, na.rm = T), 1),
	`01c_involving_municipal_agency` = round(100*mean(involved_municipal_agency, na.rm = T), 1),
	`02_share_admin_cases` = round(100*mean(caseTypeCode == "administrative", na.rm = T), 1),
	`03_share_local_entities` = round(100*mean(local_entities_only, na.rm = T), 1),
	`05_median_claim_sum` = round(median(ifelse(claimSum_deflated > 0, claimSum_deflated, NA), na.rm = T)/1000, 1),
	`06_median_days_to_decision` = round(median(days_elapsed, na.rm = T), 1),
	`07_median_court_documents_per_case` = round(median(countDocumentsByCourt, na.rm = T), 1),
	`11_share_petty_cases` = round(100*mean(petty_case, na.rm = T), 1),
	`12_share_government_plaintiff` = round(100*mean(government_plaintiff, na.rm = T), 1),
	`13a_share_tax` = round(100*mean(caseCategory_government == "Taxes, duties, and dues", na.rm = T), 1),
	`13b_share_othercivil` = round(100*mean(caseCategory_government == "Other civil law", na.rm = T), 1),
	`13c_share_adminoffences` = round(100*mean(caseCategory_government == "Administrative offences", na.rm = T), 1),
	`13d_share_otherpublic` = round(100*mean(caseCategory_government == "Other public law", na.rm = T), 1),
	`13e_share_contractbreach` = round(100*mean(caseCategory_government == "Contract breach", na.rm = T), 1),
	`13f_share_othercontract` = round(100*mean(caseCategory_government == "Other contract-related", na.rm = T), 1),
	`13g_share_other` = round(100*mean(caseCategory_government == "Other", na.rm = T), 1),
	`14_share_appealed` = round(100*mean(was_appealed, na.rm = T), 1),
	`15_share_government_win` = round(100*mean(government_win_final, na.rm = T), 1),
	`15a_share_federal_agency_win` = round(100*mean(federal_agency_win_final, na.rm = T), 1),
	`15b_share_regional_agency_win` = round(100*mean(regional_agency_win_final, na.rm = T), 1),
	`15c_share_municipal_agency_win` = round(100*mean(municipal_agency_win_final, na.rm = T), 1)
), by = "instanceLevel"]
setorderv(government_judges_table_all, "instanceLevel")
government_judges_table_all <- dcast(melt(government_judges_table_all, id.vars = "instanceLevel"), variable ~ instanceLevel)
names(government_judges_table_all)[2:3] <- paste0("all_", names(government_judges_table_all)[2:3])

# Krasnodar judges table by appeal level
government_judges_table_krasnodar <- judge_chars[ involved_government == 1 & krasnodar == 1, list(
	`01_judges` = uniqueN(judgeName),
	`02_total_government_cases` = sum(involved_government),
	`01a_involving_federal_agency` = round(100*mean(involved_federal_agency, na.rm = T), 1),
	`01b_involving_regional_agency` = round(100*mean(involved_regional_agency, na.rm = T), 1),
	`01c_involving_municipal_agency` = round(100*mean(involved_municipal_agency, na.rm = T), 1),
	`02_share_admin_cases` = round(100*mean(caseTypeCode == "administrative", na.rm = T), 1),
	`03_share_local_entities` = round(100*mean(local_entities_only, na.rm = T), 1),
	`05_median_claim_sum` = round(median(ifelse(claimSum_deflated > 0, claimSum_deflated, NA), na.rm = T)/1000, 1),
	`06_median_days_to_decision` = round(median(days_elapsed, na.rm = T), 1),
	`07_median_court_documents_per_case` = round(median(countDocumentsByCourt, na.rm = T), 1),
	`11_share_petty_cases` = round(100*mean(petty_case, na.rm = T), 1),
	`12_share_government_plaintiff` = round(100*mean(government_plaintiff, na.rm = T), 1),
	`13a_share_tax` = round(100*mean(caseCategory_government == "Taxes, duties, and dues", na.rm = T), 1),
	`13b_share_othercivil` = round(100*mean(caseCategory_government == "Other civil law", na.rm = T), 1),
	`13c_share_adminoffences` = round(100*mean(caseCategory_government == "Administrative offences", na.rm = T), 1),
	`13d_share_otherpublic` = round(100*mean(caseCategory_government == "Other public law", na.rm = T), 1),
	`13e_share_contractbreach` = round(100*mean(caseCategory_government == "Contract breach", na.rm = T), 1),
	`13f_share_othercontract` = round(100*mean(caseCategory_government == "Other contract-related", na.rm = T), 1),
	`13g_share_other` = round(100*mean(caseCategory_government == "Other", na.rm = T), 1),
	`14_share_appealed` = round(100*mean(was_appealed, na.rm = T), 1),
	`15_share_government_win` = round(100*mean(government_win_final, na.rm = T), 1),
	`15a_share_federal_agency_win` = round(100*mean(federal_agency_win_final, na.rm = T), 1),
	`15b_share_regional_agency_win` = round(100*mean(regional_agency_win_final, na.rm = T), 1),
	`15c_share_municipal_agency_win` = round(100*mean(municipal_agency_win_final, na.rm = T), 1)
), by = "instanceLevel"]
setorderv(government_judges_table_krasnodar, "instanceLevel")
government_judges_table_krasnodar <- dcast(melt(government_judges_table_krasnodar, id.vars = "instanceLevel"), variable ~ instanceLevel)
names(government_judges_table_krasnodar)[2:3] <- paste0("krasnodar_", names(government_judges_table_krasnodar)[2:3])

# Non-Krasnodar judges table by appeal level
government_judges_table_nonkrasnodar <- judge_chars[ involved_government == 1 & krasnodar == 0, list(
	`01_judges` = uniqueN(judgeName),
	`02_total_government_cases` = sum(involved_government),
	`01a_involving_federal_agency` = round(100*mean(involved_federal_agency, na.rm = T), 1),
	`01b_involving_regional_agency` = round(100*mean(involved_regional_agency, na.rm = T), 1),
	`01c_involving_municipal_agency` = round(100*mean(involved_municipal_agency, na.rm = T), 1),
	`02_share_admin_cases` = round(100*mean(caseTypeCode == "administrative", na.rm = T), 1),
	`03_share_local_entities` = round(100*mean(local_entities_only, na.rm = T), 1),
	`05_median_claim_sum` = round(median(ifelse(claimSum_deflated > 0, claimSum_deflated, NA), na.rm = T)/1000, 1),
	`06_median_days_to_decision` = round(median(days_elapsed, na.rm = T), 1),
	`07_median_court_documents_per_case` = round(median(countDocumentsByCourt, na.rm = T), 1),
	`11_share_petty_cases` = round(100*mean(petty_case, na.rm = T), 1),
	`12_share_government_plaintiff` = round(100*mean(government_plaintiff, na.rm = T), 1),
	`13a_share_tax` = round(100*mean(caseCategory_government == "Taxes, duties, and dues", na.rm = T), 1),
	`13b_share_othercivil` = round(100*mean(caseCategory_government == "Other civil law", na.rm = T), 1),
	`13c_share_adminoffences` = round(100*mean(caseCategory_government == "Administrative offences", na.rm = T), 1),
	`13d_share_otherpublic` = round(100*mean(caseCategory_government == "Other public law", na.rm = T), 1),
	`13e_share_contractbreach` = round(100*mean(caseCategory_government == "Contract breach", na.rm = T), 1),
	`13f_share_othercontract` = round(100*mean(caseCategory_government == "Other contract-related", na.rm = T), 1),
	`13g_share_other` = round(100*mean(caseCategory_government == "Other", na.rm = T), 1),
	`14_share_appealed` = round(100*mean(was_appealed, na.rm = T), 1),
	`15_share_government_win` = round(100*mean(government_win_final, na.rm = T), 1),
	`15a_share_federal_agency_win` = round(100*mean(federal_agency_win_final, na.rm = T), 1),
	`15b_share_regional_agency_win` = round(100*mean(regional_agency_win_final, na.rm = T), 1),
	`15c_share_municipal_agency_win` = round(100*mean(municipal_agency_win_final, na.rm = T), 1)
), by = "instanceLevel"]
setorderv(government_judges_table_nonkrasnodar, "instanceLevel")
government_judges_table_nonkrasnodar <- dcast(melt(government_judges_table_nonkrasnodar, id.vars = "instanceLevel"), variable ~ instanceLevel)
names(government_judges_table_nonkrasnodar)[2:3] <- paste0("nonkrasnodar_", names(government_judges_table_nonkrasnodar)[2:3])

# Grand final table
government_judges_table <- merge(government_judges_table_all, government_judges_table_krasnodar, by = "variable")
government_judges_table <- merge(government_judges_table, government_judges_table_nonkrasnodar, by = "variable")
setcolorder(government_judges_table, c("variable", "all_1_first_instance", "krasnodar_1_first_instance", "nonkrasnodar_1_first_instance"))

## Mean caseload by judge type and instance level
judge_caseload <- judge_chars[ involved_government == 1 & !is.na(krasnodar), uniqueN(caseid), by = c("instanceLevel", "judgeName", "year")]
judge_caseload <- merge(judge_caseload, unique(judge_chars[, c("judgeName", "krasnodar")], by = "judgeName"), by = "judgeName", all.x = T, all.y = F)

### All judges
judge_caseload[year == 2019, round(mean(V1), 1), by = c("instanceLevel")]
### Krasnodar judges
judge_caseload[year == 2019 & krasnodar == 1, round(mean(V1), 1), by = c("instanceLevel")]
### Non-Krasnodar judges
judge_caseload[year == 2019 & krasnodar == 0, round(mean(V1), 1), by = c("instanceLevel")]

# Export the table
fwrite(government_judges_table, file = "tables/table2_government_judges_table_krasnodar.csv")

##############################
# Judge characteristics: private vs. private disputes 
# where one of parties is outside Crimea

# All judges table by appeal level
local_entity_judges_table_all <- judge_chars[ involved_government == 0 & local_entities_only == 0 & !is.na(krasnodar), list(
	`01_judges` = uniqueN(judgeName),
	`02_total_local_entity_cases` = sum(involved_local_entity, na.rm = T),
	`05_median_claim_sum` = round(median(ifelse(claimSum_deflated > 0, claimSum_deflated, NA), na.rm = T)/1000, 1),
	`06_median_days_to_decision` = round(median(days_elapsed, na.rm = T), 1),
	`07_median_court_documents_per_case` = round(median(countDocumentsByCourt, na.rm = T), 1),
	`11_share_petty_cases` = round(100*mean(petty_case, na.rm = T), 1),
	`12_share_local_entity_plaintiff` = round(100*mean(local_entity_plaintiff, na.rm = T), 1),
	`13a_share_breachbanking` = round(100*mean(caseCategory_private == "Contract breach: insurance/banking", na.rm = T), 1),
	`13b_share_breachsupply` = round(100*mean(caseCategory_private == "Contract breach: supply", na.rm = T), 1),
	`13c_share_other` = round(100*mean(caseCategory_private == "Other", na.rm = T), 1),
	`13d_share_othercontract` = round(100*mean(caseCategory_private == "Other contract-related", na.rm = T), 1),
	`13e_share_breachworks` = round(100*mean(caseCategory_private == "Contract breach: works", na.rm = T), 1),
	`13f_share_breachservices` = round(100*mean(caseCategory_private == "Contract breach: services", na.rm = T), 1),
	`13g_share_breachenergy` = round(100*mean(caseCategory_private == "Contract breach: energy", na.rm = T), 1),
	`14_share_appealed` = round(100*mean(was_appealed, na.rm = T), 1),
	`15_share_local_entity_win` = round(100*mean(local_entity_win_final, na.rm = T), 1)
), by = "instanceLevel"]
setorderv(local_entity_judges_table_all, "instanceLevel")
local_entity_judges_table_all <- dcast(melt(local_entity_judges_table_all, id.vars = "instanceLevel"), variable ~ instanceLevel)
names(local_entity_judges_table_all)[2:3] <- paste0("all_", names(local_entity_judges_table_all)[2:3])

# Krasnodar judges table by appeal level
local_entity_judges_table_krasnodar <- judge_chars[ involved_government == 0 & local_entities_only == 0 & krasnodar == 1, list(
	`01_judges` = uniqueN(judgeName),
	`02_total_local_entity_cases` = sum(involved_local_entity, na.rm = T),
	`05_median_claim_sum` = round(median(ifelse(claimSum_deflated > 0, claimSum_deflated, NA), na.rm = T)/1000, 1),
	`06_median_days_to_decision` = round(median(days_elapsed, na.rm = T), 1),
	`07_median_court_documents_per_case` = round(median(countDocumentsByCourt, na.rm = T), 1),
	`11_share_petty_cases` = round(100*mean(petty_case, na.rm = T), 1),
	`12_share_local_entity_plaintiff` = round(100*mean(local_entity_plaintiff, na.rm = T), 1),
	`13a_share_breachbanking` = round(100*mean(caseCategory_private == "Contract breach: insurance/banking", na.rm = T), 1),
	`13b_share_breachsupply` = round(100*mean(caseCategory_private == "Contract breach: supply", na.rm = T), 1),
	`13c_share_other` = round(100*mean(caseCategory_private == "Other", na.rm = T), 1),
	`13d_share_othercontract` = round(100*mean(caseCategory_private == "Other contract-related", na.rm = T), 1),
	`13e_share_breachworks` = round(100*mean(caseCategory_private == "Contract breach: works", na.rm = T), 1),
	`13f_share_breachservices` = round(100*mean(caseCategory_private == "Contract breach: services", na.rm = T), 1),
	`13g_share_breachenergy` = round(100*mean(caseCategory_private == "Contract breach: energy", na.rm = T), 1),
	`14_share_appealed` = round(100*mean(was_appealed, na.rm = T), 1),
	`15_share_local_entity_win` = round(100*mean(local_entity_win_final, na.rm = T), 1)
), by = "instanceLevel"]
setorderv(local_entity_judges_table_krasnodar, "instanceLevel")
local_entity_judges_table_krasnodar <- dcast(melt(local_entity_judges_table_krasnodar, id.vars = "instanceLevel"), variable ~ instanceLevel)
names(local_entity_judges_table_krasnodar)[2:3] <- paste0("krasnodar_", names(local_entity_judges_table_krasnodar)[2:3])

# Non-Krasnodar judges table by appeal level
local_entity_judges_table_nonkrasnodar <- judge_chars[ involved_government == 0 & local_entities_only == 0 & krasnodar == 0, list(
	`01_judges` = uniqueN(judgeName),
	`02_total_local_entity_cases` = sum(involved_local_entity, na.rm = T),
	`05_median_claim_sum` = round(median(ifelse(claimSum_deflated > 0, claimSum_deflated, NA), na.rm = T)/1000, 1),
	`06_median_days_to_decision` = round(median(days_elapsed, na.rm = T), 1),
	`07_median_court_documents_per_case` = round(median(countDocumentsByCourt, na.rm = T), 1),
	`11_share_petty_cases` = round(100*mean(petty_case, na.rm = T), 1),
	`12_share_local_entity_plaintiff` = round(100*mean(local_entity_plaintiff, na.rm = T), 1),
	`13a_share_breachbanking` = round(100*mean(caseCategory_private == "Contract breach: insurance/banking", na.rm = T), 1),
	`13b_share_breachsupply` = round(100*mean(caseCategory_private == "Contract breach: supply", na.rm = T), 1),
	`13c_share_other` = round(100*mean(caseCategory_private == "Other", na.rm = T), 1),
	`13d_share_othercontract` = round(100*mean(caseCategory_private == "Other contract-related", na.rm = T), 1),
	`13e_share_breachworks` = round(100*mean(caseCategory_private == "Contract breach: works", na.rm = T), 1),
	`13f_share_breachservices` = round(100*mean(caseCategory_private == "Contract breach: services", na.rm = T), 1),
	`13g_share_breachenergy` = round(100*mean(caseCategory_private == "Contract breach: energy", na.rm = T), 1),
	`14_share_appealed` = round(100*mean(was_appealed, na.rm = T), 1),
	`15_share_local_entity_win` = round(100*mean(local_entity_win_final, na.rm = T), 1)
), by = "instanceLevel"]
setorderv(local_entity_judges_table_nonkrasnodar, "instanceLevel")
local_entity_judges_table_nonkrasnodar <- dcast(melt(local_entity_judges_table_nonkrasnodar, id.vars = "instanceLevel"), variable ~ instanceLevel)
names(local_entity_judges_table_nonkrasnodar)[2:3] <- paste0("nonkrasnodar_", names(local_entity_judges_table_nonkrasnodar)[2:3])

# Grand final table
local_entity_judges_table <- merge(local_entity_judges_table_all, local_entity_judges_table_krasnodar, by = "variable")
local_entity_judges_table <- merge(local_entity_judges_table, local_entity_judges_table_nonkrasnodar, by = "variable")
setcolorder(local_entity_judges_table, c("variable", "all_1_first_instance", "krasnodar_1_first_instance", "nonkrasnodar_1_first_instance"))

## Mean caseload by judge type and instance level
judge_caseload <- judge_chars[ involved_government == 0 & local_entities_only == 0 & !is.na(krasnodar), uniqueN(caseid), by = c("instanceLevel", "judgeName", "year")]
judge_caseload <- merge(judge_caseload, unique(judge_chars[, c("judgeName", "krasnodar")], by = "judgeName"), by = "judgeName", all.x = T, all.y = F)

### All judges
judge_caseload[year == 2019, round(mean(V1), 1), by = c("instanceLevel")]
### Krasnodar judges
judge_caseload[year == 2019 & krasnodar == 1, round(mean(V1), 1), by = c("instanceLevel")]
### Non-Krasnodar judges
judge_caseload[year == 2019 & krasnodar == 0, round(mean(V1), 1), by = c("instanceLevel")]

# Export the table
fwrite(local_entity_judges_table, file = "tables/table2_local_entity_judges_table_krasnodar.csv")
